package org.finmanager.core;

import com.alee.laf.WebLookAndFeel;
import com.alee.laf.button.WebButton;
import com.alee.managers.language.LanguageManager;
import org.finmanager.alert.AlertUI;
import org.finmanager.budget.BudgetManagerController;
import org.finmanager.budget.BudgetModel;
import org.finmanager.data.BudgetList;
import org.finmanager.data.CategoryList;
import org.finmanager.data.ItemList;
import org.finmanager.statistics.StatisticsController;
import org.finmanager.statistics.StatisticsModel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import static org.finmanager.core.Constants.APP_NAME;
import static org.finmanager.core.Constants.APP_HEIGHT;
import static org.finmanager.core.Constants.APP_WIDTH;

/**
 * Created by Kelvin on 3/5/14.
 * <p/>
 * This is the main class
 * The program starts by creating a frame with the home page
 */

public class FinManager {

	// This is the main component for adding other components
	// It should be added to the main frame
	private JPanel mainPanel = new JPanel(new GridLayout(1, 1));

	//The use of TAB design on top of the frame
	private JTabbedPane mainTabbedPane = new JTabbedPane();

	private ItemManagerController itemManagerController;
	private BudgetManagerController budgetManagerController;
	private StatisticsController statisticsController;

	//DATA sources from loading from .txt files
	private ItemList itemList;
	private CategoryList categoryList;
	private BudgetList budgetList;

	private CategoryModel categoryModel;
	private ItemModel itemModel;
	private BudgetModel budgetModel;
	private StatisticsModel statisticsModel;

	// Creating six buttons on the home screen and a tabbed pane
	public FinManager() {
		setUpDataAndModel();

		JPanel homePanel = new JPanel(new GridLayout(1, 3, 100, 85));
		homePanel.setBorder(BorderFactory.createEmptyBorder(225, 100, 225, 100));

		ArrayList<WebButton> buttons = new ArrayList<WebButton>();
		buttons.add(new WebButton("Budget"));
		buttons.add(new WebButton("Planning"));
		buttons.add(new WebButton("Statistics"));
		//buttons.add(new WebButton("Calendar"));
		//buttons.add(new WebButton("Comparison"));

		// Currently we only add action to the first button
		// This button cannot make multiple tab on the ItemManagerUI
		// We add a custom TabComponent containing a "close" button allowing this tab to be closed
		buttons.get(0).addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (itemManagerController == null) {
					itemManagerController = new ItemManagerController(FinManager.this);
				}
				mainTabbedPane.addTab("Budget", itemManagerController.getUIMainComponent());
				mainTabbedPane.setTabComponentAt(mainTabbedPane.getTabCount() - 1, new TabComponent(mainTabbedPane));
				mainTabbedPane.setSelectedIndex(mainTabbedPane.getTabCount() - 1);
			}
		});

		buttons.get(1).addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (budgetManagerController == null) {
					budgetManagerController = new BudgetManagerController(FinManager.this);
				}
				mainTabbedPane.addTab("Planning", budgetManagerController.getUIMainComponent());
				mainTabbedPane.setTabComponentAt(mainTabbedPane.getTabCount() - 1, new TabComponent(mainTabbedPane));
				mainTabbedPane.setSelectedIndex(mainTabbedPane.getTabCount() - 1);
			}
		});

		buttons.get(2).addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (statisticsController == null) {
					statisticsController = new StatisticsController(FinManager.this);
				}
				mainTabbedPane.addTab("Statistics", statisticsController.getUIMainComponent());

				mainTabbedPane.setTabComponentAt(mainTabbedPane.getTabCount() - 1, new TabComponent(mainTabbedPane));
				mainTabbedPane.setSelectedIndex(mainTabbedPane.getTabCount() - 1);
			}
		});

		for (WebButton button : buttons) {
			button.setRound(20);
			button.setRolloverShine(true);
			button.setFontSizeAndStyle(16, false, false);
			button.setDrawFocus(false);

			homePanel.add(button);
		}

		// The home screen is the first tab and cannot be removed
		// i.e. we should not add a "close" button to this tab
		mainTabbedPane.addTab("Home", homePanel);
		mainTabbedPane.setFocusable(false);
		
		JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
		
		WebButton alertButton = new WebButton("!");
		alertButton.setDrawFocus(false);
		alertButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				showAlert();
			}
		});

		bottomPanel.add(alertButton);
		
		getMainComponent().setLayout(new BorderLayout(0, 0));
		getMainComponent().add(mainTabbedPane, BorderLayout.CENTER);
		getMainComponent().add(bottomPanel, BorderLayout.SOUTH);

		// showAlert();
	}

	// This method returns the main panel
	private JComponent getMainComponent() {
		return mainPanel;
	}

	// This static method first creates a frame then adds the main panel to the frame while setting behaviour of the frame
	private static void createAndShowGUI() {
		FinManager finManager = new FinManager();

		JFrame.setDefaultLookAndFeelDecorated(true);
		JFrame frame = new JFrame(APP_NAME);

		frame.add(finManager.getMainComponent());

		frame.setSize(new Dimension(APP_WIDTH, APP_HEIGHT));

		// The frame is positioned in the middle of window
		frame.setLocationRelativeTo(null);

		// Closing this frame terminates the whole application
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

		// Finally, setting the frame visible
		// This method should be called last
		frame.setVisible(true);
	}

	private void setUpDataAndModel() {
		categoryList = new CategoryList();
		itemList = new ItemList(categoryList);
		budgetList = new BudgetList(categoryList);

		categoryModel = new CategoryModel(this);
		itemModel = new ItemModel(this);
		budgetModel = new BudgetModel(this);
		statisticsModel = new StatisticsModel(this);

		categoryModel.addObserver(itemModel);
		categoryModel.addObserver(budgetModel);
		categoryModel.addObserver(statisticsModel);

		itemModel.addObserver(budgetModel);
		itemModel.addObserver(statisticsModel);
	}

	public CategoryList getCategoryList() {
		return categoryList;
	}

	public ItemList getItemList() {
		return itemList;
	}

	public BudgetList getBudgetList() {
		return budgetList;
	}

	public CategoryModel getCategoryModel() {
		return categoryModel;
	}

	public ItemModel getItemModel() {
		return itemModel;
	}

	public BudgetModel getBudgetModel() {
		return budgetModel;
	}

	public StatisticsModel getStatisticsModel() {
		return statisticsModel;
	}

	public void showAlert() {
		new AlertUI(getMainComponent(), getBudgetModel().findAlmostDepletedBudgets());
	}

	public static void main(String args[]) {
		// Default demo language for now
		LanguageManager.DEFAULT = LanguageManager.ENGLISH;

		// Look and Feel
		WebLookAndFeel.install();
		WebLookAndFeel.setDecorateDialogs(true);

		FinManager.createAndShowGUI();
	}
}
